package ru.adhoc.truealarmfree.services;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.text.format.DateFormat;
import android.util.Log;

import java.util.Calendar;

import ru.adhoc.truealarmfree.R;
import ru.adhoc.truealarmfree.activities.MainActivity;
import ru.adhoc.truealarmfree.db.DbHelper;
import ru.adhoc.truealarmfree.time.TimeHelper;
import ru.adhoc.truealarmfree.utils.Constants;
import ru.adhoc.truealarmfree.utils.Util;

/**
 * Created by s_malygin on 20.11.13.
 */
public class NotificationService extends Service {

    private static final int NOTIFY_ID = 9999;
    private Context context;
    private DbHelper DbHelper;
    private boolean cancelThread;
    private Thread t;
    private boolean is24HourFormat;
    private Handler h;

    static long resetTime;
    static boolean postponed;

    private NotificationManager mNotificationManager;
    private NotificationCompat.Builder mBuilder;

    private final int STATUS_REFRESH_TIME = 0;
    private final int STATUS_END_THREAD = 1;
    private final int STATUS_POSTPONED = 2;

    private String remainTXT;
    private Long nearAlarmTime;
    private String thisAlarmTime;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        context = this.getApplicationContext();
        is24HourFormat = DateFormat.is24HourFormat(context);

        createHandler();

        if(intent != null){
            postponed = intent.getBooleanExtra("postponed", false);
            resetTime = intent.getLongExtra("resetTime",0L);
        }
        serviceTask();

        return START_REDELIVER_INTENT;
    }

    private void createHandler() {

        h = new Handler() {
            public void handleMessage(android.os.Message msg) {

                String txt;
                switch (msg.what) {
                    case STATUS_REFRESH_TIME:
                        txt = thisAlarmTime +
                                "  "+ remainTXT +" "+ getFormattedDiffTime(nearAlarmTime);
                        if(mBuilder != null && mNotificationManager != null){
                            mBuilder.setContentText(txt);
                            mNotificationManager.notify(NOTIFY_ID, mBuilder.build());
                        }
                        break;
                    case STATUS_END_THREAD:
                        txt = "Wake up...";
                        if(mBuilder != null && mNotificationManager != null){
                            mBuilder.setContentText(txt);
                            mNotificationManager.notify(NOTIFY_ID, mBuilder.build());
                        }
                        break;
                    case STATUS_POSTPONED:
                        txt = context.getResources().getString(R.string.postponedTo) +" "+ thisAlarmTime;
                        if(mBuilder != null && mNotificationManager != null){
                            mBuilder.setContentText(txt);
                            mNotificationManager.notify(NOTIFY_ID, mBuilder.build());
                        }
                        break;
                }
            };
        };
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopThread();
    }

    public IBinder onBind(Intent intent) {
        return null;
    }

    private void serviceTask() {

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        boolean hold = sp.getBoolean("hold", false);
        boolean classic = sp.getBoolean("classicOff",true);

//Получем время карйнего будильника если resetTime = 0L зачит это нотификация откладывания
        Long alarm;
        if(resetTime == 0L)
            alarm = getNearAlarmTime();
        else
            alarm = resetTime;

        nearAlarmTime = alarm;

//Получаем оставшееся время и приводим к секундам
        final long diffTimeSec = (nearAlarmTime - getRealTime())/1000;

        cancelThread = false;

        mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

        mBuilder = new NotificationCompat.Builder(context);
        mBuilder.setSmallIcon(R.drawable.ic_stat_notify);
        Bitmap bm = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
        mBuilder.setLargeIcon(bm);
        mBuilder.setContentTitle(context.getString(R.string.notificationTitle));

        Intent cancelAlarm;
        if(Constants.getInstance(context).alarmed && hold && !classic){
            cancelAlarm = Util.getInstance(context).getActualCancelAlarmIntent();
            cancelAlarm.putExtra("id", Constants.getInstance(context).alarmedID);
            cancelAlarm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        else{
            cancelAlarm = new Intent(context, MainActivity.class);
        }

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(cancelAlarm);
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(resultPendingIntent);
        mBuilder.setOngoing(true);

        thisAlarmTime = TimeHelper.getInstance(context).getTimeStringForDisplay(nearAlarmTime);

        remainTXT = context.getResources().getString(R.string.remain);

        if(!postponed && !cancelThread){
            t = new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                            int i;
                            for (i = 0; i <= diffTimeSec; i++) {
                                if(cancelThread)
                                    break;
                                h.sendEmptyMessage(STATUS_REFRESH_TIME);
                                try {
                                    t.sleep(1 * 1000);
                                } catch (InterruptedException e) {
                                    Log.e("My", "sleep failure");
                                }
                            }
                            if(!cancelThread && !postponed){
                                h.sendEmptyMessage(STATUS_END_THREAD);
                            }
                        }
                    }
            );
            t.start();
        }
        else {
            h.sendEmptyMessage(STATUS_POSTPONED);
        }

    }

    private void stopThread(){
        cancelThread = true;
        if(t != null)
            t.interrupt();
        t = null;
    }

    //Возвращает форматированную строку разности времени
    private String getFormattedDiffTime(Long nearAlarmTime){

        Long currentTime = Calendar.getInstance().getTimeInMillis();
        Long diffTime = nearAlarmTime - currentTime;
        long days = diffTime/(1000*60*60*24);
        long hours = (diffTime - (days * 86400000))/(1000*60*60);
        long minutes = (diffTime -(days * 86400000)- (hours*1000*60*60))/(1000*60);
        long sec = (diffTime - (days * 86400000)- (hours*1000*60*60)- (minutes*1000*60))/1000;

        if(days >= 1)
            return context.getResources().getString(R.string.moreThan) + " "+ days + " "+
                    context.getResources().getString(R.string.days);
        else
            return convertTimeToString24h((int) hours)+":"+convertTimeToString24h((int)minutes)+":"+
                    convertTimeToString24h((int)sec);


    }

    //convert 1 -> 01
    private String convertTimeToString24h(int num){
        String r;
        if(num == 0) r = "00";
        else if (num <= 9) r = "0"  + Integer.toString(num);
        else r = Integer.toString(num);
        return r;
    }

    //Возвращает текущее время в милисекундах
    private Long getRealTime(){
        return Calendar.getInstance().getTimeInMillis();
    }

    //Возвращает время крайнего будильника
    private Long getNearAlarmTime(){
        DbHelper = DbHelper.getInstance(context);
        SQLiteDatabase db = DbHelper.getReadableDatabase();
        Long time = 0L;

        try{
            time = DbHelper.getNearAlarmTime(db);
        }
        finally {
            if(db != null)
                db.close();
        }
        return time;
    }

}
